﻿//------------------------------------------------------------------------------
// <copyright file="RpcConversionFailureException.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace Microsoft.Internal.GamesTest.Rpc.Client
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    /// <summary>
    /// Represents a failed attempt to convert an object from one type to another.
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "Users of this class must provide a SourceType and TargetType.")]
    [Serializable]
    public class RpcConversionFailureException : RpcException
    {
        /// <summary>
        /// Initializes a new instance of the RpcConversionFailureException class.
        /// </summary>
        public RpcConversionFailureException() 
        {
        }
        
        /// <summary>
        /// Initializes a new instance of the RpcConversionFailureException class.
        /// </summary>
        /// <param name="message">A message describing the type of conversion failure.</param>
        /// <param name="sourceType">The type of the object trying to be converted.</param>
        /// <param name="targetType">The type that the object is trying to be converted to.</param>
        public RpcConversionFailureException(string message, Type sourceType, Type targetType) 
            : base(message)
        {
            this.SourceType = sourceType;
            this.TargetType = targetType;
        }
        
        /// <summary>
        /// Initializes a new instance of the RpcConversionFailureException class.
        /// </summary>
        /// <param name="message">A message describing the type of conversion failure.</param>
        /// <param name="sourceType">The type of the object trying to be converted.</param>
        /// <param name="targetType">The type that the object is trying to be converted to.</param>
        /// <param name="inner">Any applicable inner exception.</param>
        public RpcConversionFailureException(string message, Type sourceType, Type targetType, Exception inner) 
            : base(message, inner)
        {
            this.SourceType = sourceType;
            this.TargetType = targetType;
        }

        /// <summary>
        /// Initializes a new instance of the RpcConversionFailureException class.
        /// </summary>
        /// <param name="info">The SerializationInfo for this exception.</param>
        /// <param name="context">The StreamingContext for this exception.</param>
        protected RpcConversionFailureException(
          System.Runtime.Serialization.SerializationInfo info,
          System.Runtime.Serialization.StreamingContext context)
            : base(info, context) 
        {
        }

        /// <summary>
        /// Gets the type of the object trying to be converted.
        /// </summary>
        public Type SourceType { get; private set; }

        /// <summary>
        /// Gets the type of that the object was trying to be converted to.
        /// </summary>
        public Type TargetType { get; private set; }

        /// <summary>
        /// Serializes this exception.
        /// </summary>
        /// <param name="info">The SerializationInfo for this exception.</param>
        /// <param name="context">The StreamingContext for this exception.</param>
        public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            base.GetObjectData(info, context);

            info.AddValue("SourceType", this.SourceType);
            info.AddValue("TargetType", this.TargetType);
        }
    }
}
